package nacos

import (
	"errors"
	"time"

	"gitee.com/zawei/yggdrasil/pkg/config/source"
	"gitee.com/zawei/yggdrasil/pkg/utils/xstrings"
	"github.com/nacos-group/nacos-sdk-go/clients/config_client"
	"github.com/nacos-group/nacos-sdk-go/vo"
)

type watcher struct {
	client config_client.IConfigClient
	item   *item
	name   string
	cs     chan *source.ChangeSet
}

func newWatcher(client config_client.IConfigClient, name string, item *item) (*watcher, error) {
	w := &watcher{
		client: client,
		item:   item,
		name:   name,
		cs:     make(chan *source.ChangeSet, 1),
	}
	err := w.client.ListenConfig(vo.ConfigParam{
		DataId: w.item.DataID,
		Group:  w.item.Group,
		OnChange: func(namespace, group, dataId, data string) {
			cs := &source.ChangeSet{
				Priority:  source.PriorityRemote,
				Timestamp: time.Now(),
				Source:    w.name,
				Data:      xstrings.Str2bytes(data),
				Format:    w.item.Format,
			}
			cs.Checksum = cs.Sum()
			w.cs <- cs
		},
	})
	if err != nil {
		return nil, err
	}
	return w, nil
}

func (w *watcher) Next() (*source.ChangeSet, error) {
	cs, ok := <-w.cs
	if !ok {
		return nil, errors.New("watch chan closed")
	}
	return cs, nil
}

func (w *watcher) Stop() error {
	close(w.cs)
	return w.client.CancelListenConfig(vo.ConfigParam{
		DataId: w.item.DataID,
		Group:  w.item.Group,
	})
}
